package com.mfoyou.agent.web.service.common;

import com.alibaba.fastjson.JSON;
import com.mfoyou.agent.web.utils.redis.RedisCacheManger;
import org.mfoyou.agent.utils.common.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.GeoRadiusResponse;
import redis.clients.jedis.GeoUnit;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.params.geo.GeoRadiusParam;

import java.util.List;

/**
 * 地理位置服务类: 用于获取范围内的跑腿小哥
 *
 * @author hzhang7
 */
@Service
public class GeoService {

    private static final Logger logger = Logger.getLogger(GeoService.class);

    @Autowired
    private RedisCacheManger redisCacheManger;

    /**
     * 跑腿儿小哥
     */
    private static String RUNERPOS = "pos:runer:";
    /**
     * 代理商
     */
    private static String AGENTREGION = "pos:agent";
    /**
     *
     */
    private static String REGIONCUSTOMER = "pos:region:";
    /**
     * 订单
     */
    private static String ORDERPOS = "pos:order";

    /**
     * 添加订单地理位置
     *
     * @param lon
     * @param lat
     * @param orderId 订单id
     */
    public void addOrderPos(Double lon, Double lat, String orderId) {
        ShardedJedis jedis = redisCacheManger.getRedis();
        try {
            logger.info(String.format("GeoService.addOrderPos 为订单添加地址位置信息 orderId=[%s], 经度=[%s], 纬度=[%s]", orderId, lon, lat));
            jedis.geoadd(ORDERPOS, lon, lat, orderId);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisCacheManger.releaseRedis(jedis);
        }
    }

    /**
     * 移除订单id
     *
     * @param orderIds 订单ids
     */
    public void removeOrderPos(String... orderIds) {
        ShardedJedis jedis = redisCacheManger.getRedis();
        try {
            logger.info(String.format("GeoService.removeOrderPos 清除订单地址位置信息 orderIds=", JSON.toJSONString(orderIds)));
            jedis.zrem(ORDERPOS, orderIds);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisCacheManger.releaseRedis(jedis);
        }
    }

    /**
     * 获取指定范围内的订单列表
     *
     * @param lon
     * @param lat
     * @param distance 距离
     * @return
     */
    public List<GeoRadiusResponse> getOrder(Double lon, Double lat, int distance) {
        List<GeoRadiusResponse> ret = null;
        ShardedJedis jedis = redisCacheManger.getRedis();
        try {
            logger.info(String.format("GeoService.getOrder 获取指定半径范围内的订单列表 经度=[%s], 纬度=[%s], 半径=[%s]", lon, lat, distance));
            ret = jedis.georadius(ORDERPOS, lon, lat, distance, GeoUnit.M, GeoRadiusParam.geoRadiusParam().sortAscending().withDist().withCoord());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisCacheManger.releaseRedis(jedis);
        }
        return ret;
    }

    /**
     * 更新跑腿儿小哥地理位置
     *
     * @param lon
     * @param lat
     * @param runnerId 跑腿小哥id
     * @param agentId  1=顾客，2=代理商，4=跑腿员，8=商家 16=商家服务商 128=总管理
     */
    public void updateRunnerPos(Double lon, Double lat, Integer runnerId, Integer agentId) {
        ShardedJedis jedis = redisCacheManger.getRedis();
        if (agentId == null) {
            agentId = 0;
        }
        try {
            String key = RUNERPOS + agentId;
            String member = runner_makeKey("" + runnerId);
            logger.info(String.format("GeoService.updateRunnerPos 更新跑腿儿小哥位置 key=[%s], member=[%s], 经度=[%s], 纬度=[%s]", key, member, lon, lat));
            jedis.geoadd(key, lon, lat, member);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisCacheManger.releaseRedis(jedis);
        }
    }

    /**
     * 移除跑腿儿小哥地理位置
     *
     * @param agentId   1=顾客，2=代理商，4=跑腿员，8=商家 16=商家服务商 128总管理
     * @param runnerIds 跑腿小哥ids
     */
    public void removeRunnerPos(Integer agentId, Integer... runnerIds) {
        ShardedJedis jedis = redisCacheManger.getRedis();

        try {
            logger.info(String.format("GeoService.removeRunnerPos 从redis缓存中移除跑腿儿小哥地理位置信息 runnerIds=[%s]", JSON.toJSONString(runnerIds)));
            for (int i = 0; i < runnerIds.length; i++) {
                jedis.zrem(RUNERPOS + agentId, runner_makeKey("" + runnerIds[i]));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisCacheManger.releaseRedis(jedis);
        }
    }

    /**
     * 根据 用户类型、跑腿小哥地理位置和距离获取列表
     *
     * @param agentId  1=顾客，2=代理商，4=跑腿员，8=商家 16=商家服务商 128=总管理
     * @param lon
     * @param lat
     * @param distance 距离
     * @return
     */
    public List<GeoRadiusResponse> getRunner(Integer agentId, Double lon, Double lat, int distance) {
        String key = RUNERPOS + agentId;
        logger.info(String.format("GeoService.getRunner 获取跑腿小哥位置列表 key=[%s], 经度=[%s], 纬度=[%s], 半径=[%s]", key, lon, lat, distance));

        // 获取 redis 缓存对象
        ShardedJedis jedis = redisCacheManger.getRedis();
        try {
            return jedis.georadius(key, lon, lat, distance, GeoUnit.M, GeoRadiusParam.geoRadiusParam().sortAscending().withDist().withCoord());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisCacheManger.releaseRedis(jedis);
        }
        return null;
    }

    public static String runner_getUserId(String s) {
        String[] strings = s.split("\\|\\|");
        return strings[0];
    }

    public static String runner_makeKey(String... s) {
        String result = s[0];

        for (int i = 1; i < s.length; i++) {
            result += ("\\|\\|" + s[i]);
        }
        return result;
    }

    public static String agent_getAgentId(String s) {
        String[] strings = s.split("\\|\\|");
        if (strings.length >= 2) {
            return strings[0];
        }
        strings = s.split("\\\\\\|\\\\\\|");
        if (strings.length >= 2) {
            return strings[0];
        }
        return strings[0];
    }

    public static String agent_getRegionId(String s) {
        String[] strings = s.split("\\|\\|");
        if (strings.length >= 2) {
            return strings[1];
        }
        strings = s.split("\\\\\\|\\\\\\|");
        if (strings.length >= 2) {
            return strings[1];
        }
        return null;
    }
}
